package com.boarsoft.boar.deploy.plan.biz;

import java.util.List;

import org.hibernate.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.boar.deploy.entity.BuildPlanDetail;
import com.boarsoft.boar.deploy.entity.BuildPlan;
import com.boarsoft.boar.deploy.entity.BuildPlanItem;
import com.boarsoft.boar.deploy.plan.PlanItemBiz;
import com.boarsoft.boar.entity.FileInfo;
import com.boarsoft.boar.entity.FileVersion;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

@Component
public class PlanItemBizImpl extends SimpleBizImpl implements PlanItemBiz {

	@Override
	@Transactional(readOnly = true)
	public BuildPlanItem find(String planId, String code) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and planId='").append(planId)//
				.append("' and code='").append(code)//
				.append("' and type=").append(BuildPlanItem.TYPE_APP);
		return dao.find(BuildPlanItem.class, sb.toString());
	}

	@Override
	@Transactional(readOnly = true)
	public boolean exists(String planId, String targetId) {
		StringBuilder sb = new StringBuilder();
		sb.append("select count(1) from ").append(BuildPlanItem.class.getName())//
				.append(" where planId=:planId and targetId=:targetId");
		Query<Long> q = dao.createQuery(Long.class, sb.toString())//
				.setParameter("planId", planId).setParameter("targetId", targetId);
		return q.getSingleResult() > 0;
	}

	@Override
	@Transactional
	public void update(BuildPlanItem o) {
		dao.merge(o);
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<BuildPlanItem> list(String planId, Short type, String targetId, String key, String orderBy, int pageNo,
			int pageSize) {
		StringBuilder sb = new StringBuilder();
		sb.append("and planId='").append(planId);
		// 只查询手工添加的部署项
		sb.append("' and ownerId <> null");
		if (type != null) {
			sb.append(" and type=").append(type);
		}
		if (Util.strIsNotEmpty(targetId)) {
			sb.append(" and targetId='").append(targetId).append("'");
		}
		if (Util.strIsNotEmpty(key)) {
			sb.append(" and (code like '%").append(key);
			sb.append("%' or name like '%").append(key);
			sb.append("%' or memo like '%").append(key);
			sb.append("%')");
		}
		int total = dao.getTotal(BuildPlanItem.class, sb.toString());
		if (Util.strIsNotEmpty(orderBy)) {
			// String ob = Util.array2str(("e." + orderBy).replaceAll(",",
			// ",").split(","), ",");
			sb.append(" order by ").append(orderBy);
		} else {
			sb.append(" order by targetId");
		}
		List<BuildPlanItem> lt = dao.list(//
				BuildPlanItem.class, sb.toString(), pageNo, pageSize);
		return new PagedResult<BuildPlanItem>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional(readOnly = true)
	public List<BuildPlanItem> list(String planId, Short type, String targetId, String orderBy) {
		StringBuilder sb = new StringBuilder();
		if (Util.strIsNotEmpty(planId)) {
			sb.append("and planId='").append(planId).append("'");
		}
		if (type != null) {
			sb.append("and type=").append(type);
		}
		if (Util.strIsNotEmpty(targetId)) {
			sb.append("and targetId='").append(targetId).append("'");
		}
		if (Util.strIsNotEmpty(orderBy)) {
			sb.append(" order by ").append(orderBy);
		} else {
			sb.append(" order by createTime");
		}
		return dao.list(BuildPlanItem.class, sb.toString());
	}

	@Override
	@Transactional
	public ReplyInfo<Object> save(BuildPlanItem o) {
		o.setLastTime(Util.getStdmfDateTime());
		if (Util.strIsEmpty(o.getId())) {
			o.setCreateTime(Util.getStdmfDateTime());
			// 插入前先判重：planId，targetId
			if (this.exists(o.getPlanId(), o.getTargetId())) {
				log.warn("Build plan item {} already exists", o);
				return Constants.REPLY_INFO_DUPLICATED;
			}
			dao.save(o);
		} else {
			dao.merge(o);
		}
		BuildPlan p = dao.get(BuildPlan.class, o.getPlanId());
		p.setStatus(BuildPlan.STATUS_DRAFT);
		return ReplyInfo.SUCCESS;
	}

	@Override
	@Transactional
	public void delete(String id) {
		StringBuilder sb = new StringBuilder();
		// 删除当前部署项（App/Lib/File）已绑定的服务器
		sb.setLength(0);
		sb.append("delete from ").append(BuildPlanDetail.class.getName())//
				.append(" where targetId=:id");
		dao.createQuery(sb.toString())//
				.setParameter("id", id).executeUpdate();
		//
		BuildPlanItem o = dao.get(BuildPlanItem.class, id);
		// SQL和SHELL类型的文件只针对本次部署有效
		switch (o.getType()) {
		case BuildPlanItem.TYPE_SQL:
		case BuildPlanItem.TYPE_SHELL:
			// 删除添加时创建的文件和文件版本对象
			FileVersion fv = dao.get(FileVersion.class, o.getTargetId());
			dao.delete(FileVersion.class, o.getTargetId());
			dao.delete(FileInfo.class, fv.getFileId());
			break;
		}
		// 修改部署计划状态
		BuildPlan p = dao.get(BuildPlan.class, o.getPlanId());
		p.setStatus(BuildPlan.STATUS_DRAFT);
		// 删除部署计划明细
		dao.delete(o);
	}

	@Override
	@Transactional(readOnly = true)
	public BuildPlanItem get(String id) {
		return dao.get(BuildPlanItem.class, id);
	}

	@Override
	@Transactional
	public void save(String planId, List<BuildPlanItem> lt) {
		// 删除 build_detail_item
		StringBuilder sb = new StringBuilder();
		sb.append("delete from ").append(BuildPlanDetail.class.getName());
		sb.append(" where itemId in (select id from ");
		sb.append(BuildPlanItem.class.getName());
		sb.append(" where planId='").append(planId).append("')");
		dao.executeHql(sb.toString());
		// 删除 build_plan_item
		sb.setLength(0);
		sb.append("delete from ").append(BuildPlanItem.class.getName());
		sb.append(" where planId='").append(planId).append("'");
		dao.executeHql(sb.toString());
		// 插入新数据
		for (BuildPlanItem o : lt) {
			dao.save(o);
		}
		// 修改plan的状态为草稿
		BuildPlan p = (BuildPlan) dao.get(BuildPlan.class, planId);
		p.setStatus(BuildPlan.STATUS_DRAFT);
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<BuildPlanItem> list2(String planId, String key, String orderBy, int pageNo, int pageSize) {
		StringBuilder sb = new StringBuilder();
		// 只查询当前的BuildPlan
		sb.append(" and planId='").append(planId);
		// 只查询APP/SQL/SHELL
		sb.append("' and type in (")//
				.append(BuildPlanItem.TYPE_APP).append(", ")//
				.append(BuildPlanItem.TYPE_SQL).append(", ")//
				.append(BuildPlanItem.TYPE_SHELL).append(")");
		if (Util.strIsNotEmpty(key)) {
			sb.append(" and (code like '%").append(key);
			sb.append("%' or name like '%").append(key);
			sb.append("%' or memo like '%").append(key);
			sb.append("%')");
		}
		int total = dao.getTotal(BuildPlanItem.class, sb.toString());
		if (Util.strIsNotEmpty(orderBy)) {
			// String ob = Util.array2str(("e." + orderBy).replaceAll(",",
			// ",").split(","), ",");
			sb.append(" order by ").append(orderBy);
		} else {
			sb.append(" order by targetId");
		}
		List<BuildPlanItem> lt = dao.list(//
				BuildPlanItem.class, sb.toString(), pageNo, pageSize);
		return new PagedResult<BuildPlanItem>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional(readOnly = true)
	public List<BuildPlanItem> list2(String planId) {
		StringBuilder sb = new StringBuilder();
		// 只查询当前的BuildPlan
		sb.append(" and planId='").append(planId);
		sb.append("' and type in (")//
				.append(BuildPlanItem.TYPE_APP).append(", ")//
				.append(BuildPlanItem.TYPE_SQL).append(", ")//
				.append(BuildPlanItem.TYPE_SHELL).append(")");
		return dao.list(BuildPlanItem.class, sb.toString());
	}
}